#!/bin/bash
# 
# 
#   mkv2mp3
#   
# 
#   
#   Simple script aiming to extract audio from mkv's chapters and convert them into mp3 tracks, possibly with tags
#   Surely, needs some refinements, including:
#
#   -partitioning code into functions
#   -it could check for existence of ffmpeg and mkvextract before executing
#   -it should treat filenames correctly, including filenames with spaces
#
#   by Eder Carneiro
# 



get_final_time(){
 #this is somewhat gross, but should work
  fprb=$((ffprobe $1 ) 2>&1| grep Dur | cut -d: --fields=2,3,4|cut -d. -f1)
  
  echo $( echo $fprb ) 
 }


#  
#The following code was copyied and pasted from http://www.unix.com/tips-tutorials/31944-simple-date-time-calulation-bash.html
# It uses the 'date' utility for calculating time differences
#
date2stamp () {
    date --utc --date "$1" +%s
}

stamp2date (){
    date --utc --date "1970-01-01 $1 sec" "+%Y-%m-%d %T"
}

dateDiff (){
    case $1 in
        -s)   sec=1;      shift;;
        -m)   sec=60;     shift;;
        -h)   sec=3600;   shift;;
        -d)   sec=86400;  shift;;
        *)    sec=86400;;
    esac
    dte1=$(date2stamp $1)
    dte2=$(date2stamp $2)
    diffSec=$((dte2-dte1))
    if ((diffSec < 0)); then abs=-1; else abs=1; fi
    #return $((diffSec/sec*abs))
    echo $((diffSec/sec*abs))
}

#
# end of copy
#

#Maybe it's safer declaring variables and arrays before using them
declare -a flarray times titles
_artist=""
_album=""


call_ffmpeg(){

   ffmpeg -i $mkvinput -ss $1 -t $2 -b:a $3 -metadata title="$4" -metadata artist="$5" -metadata album="$6" "$7.mp3"

}


usage(){
  echo "  Usage:
	  
	  mkv2mp3 -i <mkvfile.mkv> -c <chaptersfile.txt> [options]
	  
	  options are:
	  -i <mkvfile.mkv> file from wich we shoul extract mp3 tracks
	  -c <chapters file> (from corresponding mkvfile
	  -e extract <chaptersfile.txt> from input mkvfile (using mkvextract)
	  -a <artist> add artist information on mp3 id3 tags
	  -l <album> add album information on mp3 id3 tags
	  -b <bitrate> bitrate parameter, in kbits/s for encoding mp3 
       " 
  exit
}

check_cmd(){

# Check number of command line parameters
if [[ $# -lt 2 ]]
then
  usage
else 
  while getopts "i:c:ea:l:b:" OPTION
  do
    case $OPTION in
    i)
      mkvinput=$OPTARG
      ;;
    c)
      chaptersfile=$OPTARG
      ;;
    e)
      extractch=1
      ;;
    a)
      _artist=$OPTARG
      ;;
    l)
      _album=$OPTARG
      ;;
    b)
      bitrate=$(printf "%sk" $OPTARG)
      ;;
    esac
  done


  if [[ -z $mkvinput ]]
  then
    usage
  fi

  if [[ -z $chaptersfile ]]
  then
    if [[ -z $extractch ]]
    then
      usage
    else
      mkvextract chapters -s $mkvinput > mkv_chapters.txt
      chaptersfile=mkv_chapters.txt
    fi
  fi

fi
}

#
# I think it starts from here ..
#


check_cmd $@
numlines=$(cat $chaptersfile | wc -l)
#numlines=$((numlines+1))
i=0
#since we don't want CHAPTERx= and CHAPTERxNAME=, from chapters file, we cut it out and put results into a temp file
cat $chaptersfile |cut -d= -f2 > fl2.txt



# then, transform mkvchapters file into a array
while read line
do
  flarray[$i]=$line
  #echo -e "i=$i,${flarray[$i]}"
  i=$(($i+1))
  
done < "fl2.txt"
#and remove temp file since we don't need it anymore
rm fl2.txt

#the following 'echo'commands were used for debugging purposes, as you may guess
i=0; j=0;
while [ $i -le "$numlines" ] 
do
    times[$j]=${flarray[$i]}
    #echo "j=$j, i=$i"
    i=$(($i+1))
    #echo "j=$j, i=$i"
    titles[$j]=$(echo "${flarray[$i]}")
    i=$(($i+1))
    j=$(($j+1))
    #echo "j=$j, i=$i"
done




#now we have mp3 track names into $titles[] and track times into $times[]
#so then we should take some parameters and feed them into ffmpeg
for i in $(seq 0 $((${#titles[@]}-1)))
do
  inittime=$( echo ${times[i]} | cut -d. -f1)
  if [[ $i -eq $((${#titles[@]}-1)) ]]
  then
    endtime=$(get_final_time $mkvinput)
  else
     endtime=$(echo ${times[((i+1))]} | cut -d. -f1);
  fi
  
  #maybe thats not necessary to calculate time differences, since newer ffmpeg versions accepts '-to' parameter
  duration=$(dateDiff -s "$endtime" "$inittime" ) 
  ttl=$(echo ${titles[i]} | tr -d '[:cntrl:]' | tr '[:blank:]' '_') 
  ttl_wnumber=$(printf "%02d-%s" $((i+1)) $ttl)
  #echo ${ttl_wnumber[@]}
  #echo $ttl
  
  if [[ -z $bitrate ]] 
  then
    bitrate=128k
  fi
  call_ffmpeg $inittime $duration $bitrate $ttl $_artist $_album ${ttl_wnumber[@]} ;


done







